﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace NetLogger
{
	[ComVisible( true )]
	[PermissionSet( SecurityAction.Demand, Name = "FullTrust" )]
	public class NetMapProxy
	{
		public const string MapViewPage = "localmap.html";

		private WebBrowser _mapView;
		private LinkedList<INetMapMarker> _markers;
		public event EventHandler<NetMapClickEventArgs> MapClick;

		public NetMapProxy( WebBrowser mapView )
		{
			_mapView = mapView;
			_mapView.Source = new Uri( NetActivation.WebUrl + MapViewPage );
			_mapView.ObjectForScripting = this;
			_markers = new LinkedList<INetMapMarker>();
		}

		public void OnMarkerClick( string label )
		{
			EventHandler<NetMapClickEventArgs>
				h = MapClick;

			if ( h != null )
			{
				INetMapMarker marker = ( from m in _markers
										 where m.Label == label
										 select m ).First();
				h( this, new NetMapClickEventArgs( marker ) );
			}
		}

		public void OnMapClick( double latitude, double longitude )
		{
			EventHandler<NetMapClickEventArgs>
				h = MapClick;

			if ( h != null )
				h( this, new NetMapClickEventArgs( latitude, longitude ) );
		}

		public void UpdateMarker( NetMember member )
		{
			_markers.Remove( member );
			if ( member.IsVisible )
			{
				_markers.AddLast( member );
				_mapView.InvokeScript( "updateMarker", member.Label, member.Latitude, member.Longitude, member.IconFile );
			}
			else
				_mapView.InvokeScript( "removeMarker", member.Label );
		}

		public void UpdateMarker( NetActivity activity )
		{
			if ( activity.IsVisible && !_markers.Any( m => activity.Equals( m ) ) )
			{
				_markers.AddLast( activity );
				_mapView.InvokeScript( "updateMarker", activity.Label, activity.Latitude, activity.Longitude, activity.IconFile );
			}
		}

		public void SetTempMarker( double latitude, double longitude )
		{
			_mapView.InvokeScript( "updateTempMarker", latitude, longitude );
			PanTo( "tempMarker" );
		}

		public void ClearTempMarker()
		{
			_mapView.InvokeScript( "removeMarker", "tempMarker" );
		}

		public void PanTo( string callsign )
		{
			_mapView.InvokeScript( "panToMarker", callsign );
		}
	}

	public class NetMapClickEventArgs : EventArgs
	{
		private double _latitude;
		private double _longitude;

		public NetMapClickEventArgs( INetMapMarker marker )
		{
			Marker = marker;
		}

		public NetMapClickEventArgs( double latitude, double longitude )
		{
			_latitude = Math.Round( latitude, 6 );
			_longitude = Math.Round( longitude, 6 );
		}

		public INetMapMarker Marker
		{
			get;
			private set;
		}

		public bool IsMarker
		{
			get
			{
				return Marker != null;
			}
		}

		public double Latitude
		{
			get
			{
				return IsMarker ? Marker.Latitude : _latitude;
			}
		}

		public double Longitude
		{
			get
			{
				return IsMarker ? Marker.Longitude : _longitude;
			}
		}
	}
}
